package dal;

import java.util.ArrayList;
import java.util.Calendar;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import entities.Movie;
import entities.Show;
import entities.Theater;

public class ManageShow
{
	private SessionFactory		factory;
	private static ManageShow	instance;

	@SuppressWarnings("deprecation")
	private ManageShow()
	{
		try
		{
			factory = new Configuration().configure().buildSessionFactory();
		} catch (Throwable ex)
		{
			System.err.println("Failed to create sessionFactory object." + ex);
			throw new ExceptionInInitializerError(ex);
		}
	}

	public static ManageShow getInstance()
	{
		if (instance == null)
		{
			instance = new ManageShow();
		}

		return instance;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Show> getAll()
	{
		ArrayList<Show> shows = null;
		Session session = factory.openSession();
		Transaction tx = null;
		try
		{
			tx = session.beginTransaction();
			shows = (ArrayList<Show>) session.createQuery("FROM entities.Show")
					.list();
			tx.commit();
		} catch (HibernateException e)
		{
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally
		{
			session.close();
		}

		return shows;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Show> getBy(Theater byTheater)
	{
		ArrayList<Show> shows = null;
		Session session = factory.openSession();
		Transaction tx = null;
		Query q = null;

		try
		{
			tx = session.beginTransaction();
			q = session
					.createQuery("FROM entities.Show WHERE theater_id  = :t");
			q.setParameter("t", byTheater.getID());
			shows = (ArrayList<Show>) q.list();

			tx.commit();
		} catch (HibernateException e)
		{
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally
		{
			session.close();
		}

		return shows;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Show> getBy(Movie byMovie)
	{
		ArrayList<Show> shows = null;
		Session session = factory.openSession();
		Transaction tx = null;
		Query q = null;

		try
		{
			tx = session.beginTransaction();
			q = session.createQuery("FROM entities.Show WHERE movie_id  = :t");
			q.setParameter("t", byMovie.getID());
			shows = (ArrayList<Show>) q.list();
			tx.commit();
		} catch (HibernateException e)
		{
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally
		{
			session.close();
		}

		return shows;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Show> getBy(Movie byMovie, Theater byTheater)
	{
		ArrayList<Show> shows = null;
		Session session = factory.openSession();
		Transaction tx = null;
		Query q = null;

		try
		{
			tx = session.beginTransaction();
			q = session
					.createQuery("FROM entities.Show WHERE movie_id  = :m AND theater_id = :t");
			q.setParameter("m", byMovie.getID());
			q.setParameter("t", byTheater.getID());
			shows = (ArrayList<Show>) q.list();

			tx.commit();
		} catch (HibernateException e)
		{
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally
		{
			session.close();
		}

		return shows;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Show> getBy(Calendar fromDate, Calendar toDate)
	{
		ArrayList<Show> shows = null;
		Session session = factory.openSession();
		Transaction tx = null;
		Query q = null;

		try
		{
			tx = session.beginTransaction();
			q = session
					.createQuery("FROM entities.Show WHERE show_date between :l AND :U");
			q.setParameter("l", fromDate);
			q.setParameter("U", toDate);
			shows = (ArrayList<Show>) q.list();

			tx.commit();
		} catch (HibernateException e)
		{
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally
		{
			session.close();
		}

		return shows;
	}

	public ArrayList<Integer> add(ArrayList<Show> showsToAdd)
	{
		ArrayList<Integer> IDsAdded = new ArrayList<Integer>();

		for (Show showToAdd : showsToAdd)
		{
			IDsAdded.add(this.add(showToAdd));
		}

		return IDsAdded;
	}

	public Integer add(Show showToAdd)
	{
		Session session = factory.openSession();
		Transaction tx = null;
		Integer showID = null;

		try
		{
			tx = session.beginTransaction();
			showID = (Integer) session.save(showToAdd);
			tx.commit();
		} catch (HibernateException e)
		{
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally
		{
			session.close();
		}
		return showID;
	}

	public void update(Integer ShowID, Calendar date)
	{
		Session session = factory.openSession();
		Transaction tx = null;
		try
		{
			tx = session.beginTransaction();
			Show show = (Show) session.get(Show.class, ShowID);
			show.setShowDate(date);
			session.update(show);
			tx.commit();
		} catch (HibernateException e)
		{
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally
		{
			session.close();
		}
	}

	public void delete(Integer showID)
	{
		Session session = factory.openSession();
		Transaction tx = null;
		try
		{
			tx = session.beginTransaction();
			Show show = (Show) session.get(Show.class, showID);
			session.delete(show);
			tx.commit();
		} catch (HibernateException e)
		{
			if (tx != null)
				tx.rollback();
			e.printStackTrace();
		} finally
		{
			session.close();
		}
	}
}
